# !/usr/bin/python
# -*- coding: utf-8 -*-

"""
@contact: 微信 1257309054
@file: quick.py
@time: 2022/7/25 21:36
@author: LDC
"""
'''
7、快速排序（quickSort）
快速排序是对冒泡排序的改进
快排的思想：首先任意选取一个数据（通常选用数组的第一个数）作为关键数据，
然后将所有比它小的数都放到它前面，所有比它大的数都放到它后面，
这个过程称为一趟快速排序。

一趟快速排序的算法是：
1）设置两个变量i、j，排序开始的时候：i=0，j=N-1；
2）以第一个数组元素作为关键数据，赋值给key，即key=A[0]；
3）从j开始向前搜索，即由后开始向前搜索(j–)，找到第一个小于key的值A[j]，
将A[j]和A[i]互换；
4）从i开始向后搜索，即由前开始向后搜索(i++)，找到第一个大于key的A[i]，
将A[i]和A[j]互换；
5）重复第3、4步，直到i=j； (3,4步中，没找到符合条件的值，
即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值，使得j=j-1，i=i+1，
直至找到为止。找到符合条件的值，进行交换的时候i， j指针位置不变。
另外，i==j这一过程一定正好是i+或j-完成的时候，此时令循环结束）。

时间复杂度：O(nlgn)
快速排序是原地排序，不需要返回值
'''
import random
import time


def parttion(list1, left, right):  # 找到中间那个数
    key = list1[left]  # 以第一个数组元素作为关键数据
    while left < right:
        # 由后开始向前搜索(right--)，找到第一个小于key的值A[right]，将A[left]和A[right]互换
        while left < right and list1[right] >= key:
            right -= 1
        list1[left] = list1[right]
        # 由前开始向后搜索(left++)，找到第一个大于key的A[left]，将A[right]和A[left]互换；
        while left < right and list1[left] <= key:
            left += 1
        list1[right] = list1[left]
        list1[left] = key
    return left


def quickSort(list1, left, right):
    if left < right:
        # 先对序列排序，并找到一个元素A，这个元素的特点是：左边的所有元素<=A,右边的所有元素>=A
        p = parttion(list1, left, right)
        quickSort(list1, left, p)  # 对A的左边进行递归，重复过程parttion()
        quickSort(list1, p + 1, right)  # 对A的右边进行递归，重复过程parttion()


if __name__ == '__main__':
    list1 = [random.randint(1, 999) for i in range(10000)]
    list11 = list1.copy()
    start1 = time.perf_counter()
    quickSort(list1, 0, len(list1) - 1)
    end1 = time.perf_counter()
    print("快速排序(递归)", end1 - start1)

    start2 = time.perf_counter()
    list4 = sorted(list11)
    end2 = time.perf_counter()
    print("函数sorted排序", end2 - start2)
    print("排序结果", list1 == list4)
